package System;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Date;
import DataTags.DataTagsAdapter;
import DataTags.DataTagsAdapterDB;
import DataTags.DataTagsToFiles;
import Logs.Log;

/**
 * this class responsible for the window that opens every time 
 * file created and is needed to be tagged. 
 * @author oz
 * @author Shinichi
 */
public class Classifier {
	/**
	 * This class takes your file
	 * and tag it , according to default tagging algorithm or the algorithm you 
	 * previously have chosen.
	 */
	private DataTagsAdapter myDataTagsToFiles;
	private Log myLog;//it tells the log if there is any change in the files tags
	private String ClassifingAlg;
	private String path;/*="/home/ozreut/workspace/j2/1/logics/";// this can be change when the path to the logics dir. is changed*/
	
	//private ClasifingAlgorithm myAlgo;
	public Classifier(){
			try {
				this.ReadFavoriteAlgo();
				//a generic implementation of path
                File f = new File("");
                path=new String(f.getAbsolutePath());
                path+="\\logics\\";
			} catch (Exception e) {}
		
		//ClassifingAlg="ClasifyByPath";/* by defult it by path*/
		DataTagsToFiles tags=new DataTagsToFiles();
		myDataTagsToFiles=new DataTagsAdapterDB(tags);
	}
	/**
	 * this method return the algorithm we use now
	 * @return the class of the algorithm we use now
	 */
	public ClasifingAlgorithm getAlgorithmInts() throws Exception  {
		File f=new File(path);// some folder's path like "D:\\myClasses\\"
		URL url;
		url = f.toURL();
		//--> "file:/D:/myClasses/..."
		URL[] urls=new URL[]{url};
		// create a new class loader for this directory
		ClassLoader cl=new URLClassLoader(urls);
		// load the class file "MyAlgo.class"
		Class<ClasifingAlgorithm> c = (Class<ClasifingAlgorithm>) cl.loadClass(ClassifingAlg);
		ClasifingAlgorithm a=c.newInstance();//c.newInstance();
		return a;
	}
	/**
	 * this method we change the default  algorithm by changing what is written in the file
	 */
	private void changeDefaultAlg() throws IOException{
		File f=new File(path+"logics_default.txt");
		//String defaultAlg="ClasifyByPath";
		//String st="ClasifyByPath";
		BufferedWriter b=new BufferedWriter(new FileWriter(f));
		b.write(ClassifingAlg);
		b.newLine();
		b.close();
	}
	/**
	 * this method change the algorithm we use according to the user choice
	 */
	public String  setAlgorithm(String fileName) throws Exception {
		ClassifingAlg=fileName.split(".class")[0];
		this.changeDefaultAlg();
		return getAlgorithmInts().getDescription();
	}
	/**
	 * this method returns the tags of our file according to the algorithm we set earlier
	 * @param f
	 * @return
	 * @throws Exception
	 */
	public String[]getTags(File f) throws Exception{
		return getAlgorithmInts().getTags(f);
	}
	/**
	 * autoTagging -with this method we can tag file automatically,
	 * then we can  loop on all the files in the listening sources
	 * @throws Exception
	 */
	public void autoTagging(File f)throws Exception {
		//System.out.println(getAlgorithmInts().getDescription());
		String[] tags=this.getTags(f);//first - gets the tags according to selected algorithm
		this.insertTagToFile(tags, f);//second- insert this file and tags into the tagging system DB
	}

	/**
	 * this method takes a file and its tags and inserts them  into the DB
	 * @param tags
	 * @param fileName
	 */
	public void insertTagToFile(String[]tags,File fileName) {
		Date d=	new Date(fileName.lastModified());
		String m_date =d.toGMTString();
		myDataTagsToFiles.addTagsTo(fileName.getName(), m_date, fileName.getPath(), tags);
		//this.notifyLog(fileName.getName()+"  tagged");
	}

	/**
	 * Description of the method notifyLog.
	 */
	public void notifyLog(String whattoNotify) {
		myLog.update(whattoNotify);
	}


	/**
	 *you enter a file and this method delete all its tags,
	 *and also the file (it has no tags so it doesn't belong to the tagging system)
	 */
	public void deleteTagToFile(File f) {
		myDataTagsToFiles.deleteFile(f);
		//this.notifyLog();
	}

	/**
	 * this method read the default algorithm from file,
	 * (it stores in file in order to save the user favorite classifying algorithm
	 */
	private void ReadFavoriteAlgo() throws Exception{
		File f=new File(path+"logics_default.txt");
		String defaultAlg="ClasifyByPath";
		String st="ClasifyByPath";
		if((f.exists())&&(f.isFile())){
			BufferedReader b=new BufferedReader(new FileReader(f));
			if((st=b.readLine())!=null){
				defaultAlg=st.trim();
			}			
			b.close();
		}
		ClassifingAlg=defaultAlg;
		
	}
	/**
	 * when we want to change file tag to a different file tag,
	 * for example- when the tag was misspelled.
	 * @param file f 
	 * @param String oldTag - the one you want to change 
	 * @param String newTag- the tag after the change
	 */
	public void changeTagsToFile(File f,String oldTag,String newTag) {
		myDataTagsToFiles.deleteOneTag(f, oldTag);
		String[]tags=(newTag+"@").split("@");
		Date d=new Date(f.lastModified());
		String lastMod=new String(d.toGMTString());
		myDataTagsToFiles.addTagsTo(f.getName(), lastMod, f.getPath(), tags);
	}
}